﻿using CoreShop.App.Units.Interface;
using CoreShop.Library;
using CoreShop.Model;
using CoreShop.Model.FromBody;
using CoreShop.PrintService;
using CoreShop.Services;
using Loading;
using MySqlX.XDevAPI.Common;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using PluSoft.Data;
using SqlSugar;
using SqlSugar.Extensions;
using Sunny.UI;
using Sunny.UI.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using static CoreShop.Library.GlobalEnumVars;
using static CoreShop.Services.PosRemoteServices;

namespace CoreShop.App
{
    public partial class frmFoodRefund : UIForm
    {
        //private decimal orderAmount = 0;//订单金额
        private long orderId = 0;
        private List<corecmsfoodtag> tagList = null;
        private corecmsfoodordermaster ordermaster = null;
        private List<corecmsfoodorderdetail> orderingDetail = null;
        private List<corecmsfoodorderpayment> orderPayList = null;
        OpaqueCommand cmd = new OpaqueCommand();
        public frmFoodRefund(corecmsfoodordermaster _ordermaster)
        {
            ordermaster = _ordermaster;
            orderId = _ordermaster.orderId;
            InitializeComponent();
        }

        private void frmFoodRefund_Shown(object sender, System.EventArgs e)
        {
            LoadOrderData();
            txtSearch.Focus();
        }

        private void LoadOrderData()
        {
            ordermaster = new corecmsfoodordermasterServices().GetById(orderId);
            if (ordermaster == null)
            {
                UIMessageBox.Show("没有可退单的数据。", "退货出错:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }

            BindOrdering(ordermaster.orderId);
            BindOrderPay(ordermaster.orderId);
        }

        private string GetPayItemName(long id)
        {
            return "uiPayItem_" + id.ToString();
        }

        private string GetMenuItemName(long orderingId)
        {
            return "uiMenuItem_" + orderingId.ToString();
        }

        private void BindOrdering(long orderId)
        {
            try
            {
                layOrdering.Visible = false;
                orderingDetail = new corecmsfoodorderdetailServices().AsQueryable().Where(p => p.orderId == orderId).ToList();
                if ((orderingDetail == null) || (orderingDetail.Count == 0))
                {
                    ordermaster = null;
                } 
                else
                {
                    var detailIds = orderingDetail.Select(p => p.id).ToList();
                    //已退部分。
                    var orderingRefunds = new corecmsfoodorderdetailServices().AsQueryable()
                        .Where(p => detailIds.Contains(p.sourceId) && p.dataType == (int)Library.GlobalEnumVars.OrderingDataType.Refund).ToList();

                    layOrdering.Clear();
                    decimal canRefunAmt = 0;//可退款金额
                    foreach (var item in orderingDetail)
                    {
                        //计算已退数量
                        var refundQty = orderingRefunds.Where(p=>p.sourceId == item.id).Sum(p=>p.quantity);
                        refundQty = -refundQty;
                        if ((item.quantity > refundQty) && (item.quantity != 0))
                        {
                            item.canRefundQty = item.quantity - refundQty;
                            layOrderingRow(item);
                            canRefunAmt += item.canRefundQty * (item.allAmount / item.quantity);
                        }
                    }
                    lblCanRefunAmt.Text = canRefunAmt.ToString("0.00#");
                }                
            }
            catch (Exception ex)
            {
                UIMessageBox.Show(ex.Message, "系统出错-BindOrdering:", UIStyle.Green, UIMessageBoxButtons.OK);
            }
            finally
            {
                layOrdering.Visible = true;
            }
        }

        private void BindOrderPay(long orderId)
        {
            orderPayList = new corecmsfoodorderpaymentServices().AsQueryable().Where(p => p.orderId == orderId).OrderBy(p=>p.id,OrderByType.Desc).ToList();
            if (orderPayList.Count > 0)
            {
                layPayList.Visible = false;
                layPayList.Clear();
                //orderAmount = 0;
                foreach (var item in orderPayList)
                {
                    decimal payAmountReturn = new corecmsfoodorderpaymentServices().AsQueryable().Where(p => p.sourceId == item.id).Sum(p=>p.payAmount);//已退金额
                    item.canRefundAmount = item.payAmount + payAmountReturn;
                    item.sourceId = item.id;
                    if (item.payAmount+ payAmountReturn > 0)
                    {
                        UPaymentnfo info = new UPaymentnfo();
                        info.Name = EnumHelper.GetEnumByValue<GlobalEnumVars.Payment>(item.paymentId);
                        info.Amount = item.payAmount.ToString();
                        info.Price = "0.00";
                        info.IsReturning = true;
                        UIMenuItemPay menu = new UIMenuItemPay(info);
                        menu.Name = GetPayItemName(item.id);
                        menu.SetMinSize();
                        layPayList.Add(menu);
                    }

                    //orderAmount += item.payAmount;
                }
                layPayList.Visible = true;
            }
        }

        /// <summary>
        /// 刷新绑定数据
        /// </summary>
        /// <param name="orderId"></param>
        private void BindOrderPayResh()
        {
            try
            {
                if (orderPayList.Count == 0)
                {
                    orderPayList.Clear();
                    return; 
                }

                decimal dRefundAmount = CommFunc.ConvertToDecimal(sumAllAmount.Text);
                foreach (var item in orderPayList)
                {                    
                    item.takeAmount = 0;                    
                    var mControl = layPayList.Get(GetPayItemName(item.id));
                    var menu = (UIMenuItemPay)mControl;
                    UPaymentnfo info = menu.Info;
                    info.Price = "0.0";
                    if (dRefundAmount <= 0) continue;

                    //用takeAmount来暂时存放退款金额
                    if (item.canRefundAmount >= dRefundAmount)
                    {                        
                        item.takeAmount = dRefundAmount;
                        dRefundAmount = 0;
                    } 
                    else
                    {
                        item.takeAmount = item.canRefundAmount;
                        dRefundAmount = dRefundAmount - item.takeAmount;
                    }
                    info.Price = item.takeAmount.ToString("0.00");
                    menu.Refresh();
                }     
            }
            catch (Exception ex)
            {
                UIMessageBox.Show(ex.Message, "系统出错-BindOrdering:", UIStyle.Green, UIMessageBoxButtons.OK);
            }
        }


        private void layOrderingRow(corecmsfoodorderdetail item)
        {
            if (item.quantity > 1)
            {
                UIReturnItem2 item2 = new UIReturnItem2();
                item2.Tag = "2";
                item2.Name = GetMenuItemName(item.id);
                item2.DishName = item.name;
                item2.SpecName = item.specName;
                item2.UnitName = item.unitName;
                item2.Number = CommFunc.FormatDecimal(item.canRefundQty);
                item2.MaxNumber = item.quantity;
                item2.RefundQuantity = "0";
                item2.Amount = item.allAmount.ToString();
                item2.Price = item.realPrice.ToString("#0.0#") + "/" + item.unitName;
                item2.txtRefundQuantity.TextChanged += MenuItem_Click; 
                layOrdering.Add(item2);
            }
            else
            {
                UIReturnItem1 item1 = new UIReturnItem1();
                item1.Name = GetMenuItemName(item.id);
                item1.Tag = "1";
                item1.DishName = item.name;
                item1.SpecName = item.specName;
                item1.UnitName = item.unitName;
                item1.Number = CommFunc.FormatDecimal(item.quantity);
                item1.SelectFlag = false;
                item1.Money = item.allAmount.ToString();
                item1.Price = item.realPrice.ToString("#0.0#") + "/" + item.unitName;
                item1.chbSelectFlag.CheckedChanged += MenuItem_Click;
                layOrdering.Add(item1);
            }
        }

        private void MenuItem_Click(object sender, System.EventArgs e)
        {
            SetSelectDetail();
            BindOrderPayResh();
        }


        private void uiButton3_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        private void frmFoodRefund_Load(object sender, System.EventArgs e)
        {
            tagList = new corecmsfoodtagServices().QueryAsync((int)GlobalEnumVars.FoodTag.RefundTag);
            mbtRefundTag.Clear();
            mbtRefundTag.MaxSelected = 1;
            mbtRefundTag.AutoWidth = true;
            foreach (var item in tagList)
            {
                mbtRefundTag.Add(item.content, item.id);
            }
        }

        private void btnSelectAll_Click(object sender, EventArgs e)
        {
            foreach (var item in orderingDetail)
            {
                var mControl = layOrdering.Get(GetMenuItemName(item.id));
                if (mControl != null)
                {
                    var mTag = mControl.Tag.ObjToInt(1);
                    if (mTag == 1)
                    {
                        var menu1 = (UIReturnItem1)mControl;
                        menu1.SelectFlag = true;
                    }
                    else
                    {
                        var menu2 = (UIReturnItem2)mControl;
                        menu2.RefundQuantity = item.canRefundQty.ToString("0.#");
                    }
                }
            }
        }
        private void SetSelectDetail()
        {            
            decimal selRefundAmt = 0;//选择的退款金额            
            foreach (var item in orderingDetail)
            {
                item.limitBuyQty = 0;
                if (item.quantity == 0) continue;
                var mControl = layOrdering.Get(GetMenuItemName(item.id));
                if (mControl == null) continue;
                item.dataType = (int)GlobalEnumVars.OrderingDataType.Normal;
                decimal refundQuantity = 0;
                var mTag = mControl.Tag.ObjToInt(1);
                if (mTag == 1)
                {
                    var menu1 = (UIReturnItem1)mControl;
                    if (menu1.SelectFlag) refundQuantity = item.quantity;
                }
                else
                {
                    var menu2 = (UIReturnItem2)mControl;
                    refundQuantity = menu2.RefundQuantity.ObjToDecimal(0);
                }
                if (refundQuantity == 0) continue;
                selRefundAmt += refundQuantity * (item.allAmount / item.quantity);
                item.limitBuyQty = refundQuantity;//暂时用limitBuyQty这个字段来存放退货数量
                item.dataType = (int)GlobalEnumVars.OrderingDataType.Refund;
            }
            sumAllAmount.Text = selRefundAmt.ToString("0.00#");
        }

        private long GetOrderingTag()
        {
            UIButton btn = mbtRefundTag.SelectedBtn;
            if (btn == null) return 0;
            long tagId = CommFunc.ConvertToInt64(btn.Tag);
            return tagId;
        }

        private async void btnRefundAll_Click(object sender, EventArgs e)
        {
            List<corecmsfoodorderpayment> orderPayment = orderPayList.Where(p=>p.takeAmount != 0).ToList();
            if ((orderPayment == null) || (orderPayment.Count == 0))
            {
                UIMessageBox.Show("没有可退款的数据。", "退款失败:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            await setRefundOrderAsync(orderPayment);                      
        }

        private async Task setRefundOrderAsync(List<corecmsfoodorderpayment> orderPayment)
        {
            if ((orderingDetail == null) || (orderingDetail.Count == 0))
            {
                UIMessageBox.Show("没有可退货的数据。", "退款失败:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            string msg = "确认要对选择的单据进行退单吗？";
            if (!ShowAskDialog(msg)) return;
            cmd.ShowOpaqueLayer(pnl_Form, 125, true);
            try
            {
                List<corecmsfoodorderdetail> refundDetail = orderingDetail.Where(p => p.dataType == (int)GlobalEnumVars.OrderingDataType.Refund).ToList();            
                long tagId = GetOrderingTag();
                OrderRefundPost orderRefund = new OrderRefundPost();
                orderRefund.tagId = tagId;

                //转换后再进行修改，不然影响到原来的对象
                string strDetail = JsonConvert.SerializeObject(refundDetail);
                orderRefund.orderDetail = JsonConvert.DeserializeObject<List<corecmsfoodorderdetail>>(strDetail);
                foreach (var item in orderRefund.orderDetail)
                {
                    decimal quantity = item.quantity;
                    item.quantity = item.limitBuyQty;
                    if ((quantity != item.limitBuyQty) && (quantity != 0))
                    {
                        decimal convert = item.limitBuyQty / quantity;
                        item.feedAmount = item.feedAmount * convert;
                        item.taskAmount = item.taskAmount * convert;
                        item.allAmount1 = item.allAmount1 * convert;
                        item.reduceAmount = item.reduceAmount * convert;
                        item.amount = item.price * item.quantity;
                        item.realAmount = item.realPrice * item.quantity;
                        item.allAmount = item.allAmount * convert;
                        item.limitBuyQty = 0;
                    }
                }

                string strMaster = JsonConvert.SerializeObject(ordermaster);
                orderRefund.orderMaster = JsonConvert.DeserializeObject<corecmsfoodordermaster>(strMaster);
                orderRefund.orderMaster.sumQuantity = orderRefund.orderDetail.Sum(p=>p.quantity);
                orderRefund.orderMaster.sumAmount = orderRefund.orderDetail.Sum(p => p.amount);
                orderRefund.orderMaster.sumRealAmount = orderRefund.orderDetail.Sum(p => p.realAmount);
                orderRefund.orderMaster.sumTaskAmount = orderRefund.orderDetail.Sum(p => p.taskAmount);
                orderRefund.orderMaster.sumFeedAmount = orderRefund.orderDetail.Sum(p => p.feedAmount);
                orderRefund.orderMaster.sumPresentAmount = orderRefund.orderDetail.Where(p=>p.realAmount == 0).Sum(p => p.amount);
                orderRefund.orderMaster.sumReduceAmount = orderRefund.orderDetail.Sum(p => p.reduceAmount);
                orderRefund.orderMaster.sumAllAmount = orderRefund.orderDetail.Sum(p => p.allAmount);
                orderRefund.orderMaster.sumAllAmount1 = orderRefund.orderDetail.Sum(p => p.allAmount1);

                string strPayment = JsonConvert.SerializeObject(orderPayment);
                orderRefund.orderPayment = JsonConvert.DeserializeObject<List<corecmsfoodorderpayment>>(strPayment);
                foreach (var item in orderRefund.orderPayment)
                {
                    item.payAmount = item.takeAmount;
                }
            
                if (!(await OrderRefundUtil.SetRefundPayment(this, orderRefund)))
                {
                    UIMessageBox.Show(msg, "退款失败:", UIStyle.Green, UIMessageBoxButtons.OK);
                    return;
                }
                var orderingService = new corecmsfoodorderingServices();
                if (!new corecmsfoodordermasterServices().SetOrderRefund(orderRefund, AppConstVars.classId, AppConstVars.sysStore, ref msg))
                {
                    UIMessageBox.Show(msg, "退款失败:", UIStyle.Green, UIMessageBoxButtons.OK);
                    this.DialogResult = System.Windows.Forms.DialogResult.Abort;
                }
                else
                {
                    OrderApiUtil.SendOrderUp(AppConstVars.sysUser, AppConstVars.sysStore, AppConstVars.classNumber, orderRefund.orderMaster.orderId);
                    new PrintServices().SetPrintSettlement(orderRefund.orderMaster, false);
                    UIMessageBox.Show(msg, "退货成功.", UIStyle.Green, UIMessageBoxButtons.OK);
                    this.DialogResult = System.Windows.Forms.DialogResult.OK;
                }
            }
            catch (Exception ex) { }
            finally
            {
                cmd.HideOpaqueLayer();
            }
        }

        private async void btnSetCashPay_Click(object sender, EventArgs e)
        {
            decimal dRefundAmount = CommFunc.ConvertToDecimal(sumAllAmount.Text);
            if (dRefundAmount == 0)
            {
                UIMessageBox.Show("没有可退款的数据。", "退款失败:", UIStyle.Green, UIMessageBoxButtons.OK);
                return;
            }
            List<corecmsfoodorderpayment> orderPayment = new List<corecmsfoodorderpayment>();
            corecmsfoodorderpayment posPay = new corecmsfoodorderpayment();
            posPay.id = (long)YitIdHelper.NextId();//先给付值，方便删除行
            posPay.orderId = ordermaster.orderId;
            posPay.paymentId = (int)GlobalEnumVars.Payment.cash;
            posPay.payName = EnumHelper.GetEnumByValue<GlobalEnumVars.Payment>(posPay.paymentId);
            posPay.payAmount = dRefundAmount;
            posPay.takeAmount = dRefundAmount;
            posPay.status = (int)GlobalEnumVars.OrderPayStatus.IsPay;
            orderPayment.Add(posPay);
            await setRefundOrderAsync(orderPayment);
        }

        private void btnSerach_Click(object sender, EventArgs e)
        {
            if (txtSearch.Text.IsNullOrEmpty()) 
            {
                ShowInfoTip("没有录入搜索内容");
                return;
            }
            string sCode = txtSearch.Text.Trim();
            var item = orderingDetail.Find(p => (p.number == sCode || p.code == sCode) && (p.canRefundQty > p.limitBuyQty));
            if (item != null)
            {
                var mControl = layOrdering.Get(GetMenuItemName(item.id));
                if (mControl != null)
                {
                    var mTag = mControl.Tag.ObjToInt(1);
                    if (mTag == 1)
                    {
                        var menu1 = (UIReturnItem1)mControl;
                        menu1.SelectFlag = true;
                    }
                    else
                    {
                        var menu2 = (UIReturnItem2)mControl;
                        menu2.RefundQuantity = item.canRefundQty.ToString("0.#");
                    }
                    txtSearch.Clear();                    
                }
            }
            else
            {
                ShowInfoTip("录入的内容在本单未找到。");
            }
            txtSearch.Focus();
            txtSearch.SelectAll();
        }

        private void txtSearch_OkButtonClick(object sender, string value)
        {
            btnSerach_Click(null, null);
        }

        private void txtSearch_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13) btnSerach_Click(null, null);
        }
    }
}
